/*
 * UStringMap.cpp
 *
 *  Created on: 2020年3月24日
 *      Author: chuanjiang.zh
 */

#include "UStringMap.h"
#include <map>

#include <sstream>
#include <cstring>


class UStringMapPrivate : public std::map< UString, UString >
{
public:

};


UStringMap::UStringMap():
	m_pimpl(new UStringMapPrivate())
{
}

UStringMap::~UStringMap()
{
	delete m_pimpl;
}

UStringMap::UStringMap(const UStringMap& strMap):
		m_pimpl(new UStringMapPrivate())
{
	*m_pimpl = *strMap.m_pimpl;
}

UStringMap& UStringMap::operator = (const UStringMap& strMap)
{
	*m_pimpl = *strMap.m_pimpl;
	return *this;
}

int UStringMap::size() const
{
	return (int)m_pimpl->size();
}

bool UStringMap::empty() const
{
	return m_pimpl->empty();
}

bool UStringMap::getAt(int idx, UString& key, UString& value) const
{
	if (idx < 0 || idx >= size())
	{
		return false;
	}

	UStringMapPrivate::iterator it = m_pimpl->begin();
	std::advance(it, idx);
	key = it->first;
	value = it->second;
	return true;
}

bool UStringMap::find(const UString& key, UString& value) const
{
	bool found = false;
	UStringMapPrivate::iterator it = m_pimpl->find(key);
	if (it != m_pimpl->end())
	{
		value = it->second;
		found = true;
	}
	return found;
}

UStringMap& UStringMap::put(const UString& key, const UString& value)
{
	(*m_pimpl)[key] = value;
	return *this;
}

bool UStringMap::remove(const UString& key, UString& value)
{
	bool found = false;
	UStringMapPrivate::iterator it = m_pimpl->find(key);
	if (it != m_pimpl->end())
	{
		value = it->second;

		m_pimpl->erase(it);
		found = true;
	}
	return found;
}

bool UStringMap::remove(const UString& key)
{
	bool found = false;
	UStringMapPrivate::iterator it = m_pimpl->find(key);
	if (it != m_pimpl->end())
	{
		m_pimpl->erase(it);
		found = true;
	}
	return found;
}

bool UStringMap::removeAt(int idx, UString& key, UString& value)
{
	if (idx < 0 || idx >= size())
	{
		return false;
	}

	UStringMapPrivate::iterator it = m_pimpl->begin();
	std::advance(it, idx);
	key = it->first;
	value = it->second;
	m_pimpl->erase(it);
	return true;
}

bool UStringMap::removeFirst(UString& key, UString& value)
{
	bool found = false;
	if (size() > 0)
	{
		UStringMapPrivate::iterator it = m_pimpl->begin();
		key = it->first;
		value = it->second;

		m_pimpl->erase(it);
		found = true;
	}
	return found;
}


bool UStringMap::contains(const UString& key) const
{
	return m_pimpl->find(key) != m_pimpl->end();
}


UString UStringMap::join(char separator, char eq) const
{
	std::ostringstream ss;
	int count = 0;
	for (UStringMapPrivate::const_iterator it = m_pimpl->begin(); it != m_pimpl->end(); ++ it)
	{
		if (count != 0)
		{
			ss << separator;
		}

		ss << it->first << eq << it->second;
		count ++;
	}
	return UString(ss.str());
}

UString UStringMap::join(const UString& separator, const UString& eq) const
{
	std::ostringstream ss;
	int count = 0;
	for (UStringMapPrivate::const_iterator it = m_pimpl->begin(); it != m_pimpl->end(); ++ it)
	{
		if (count != 0)
		{
			ss << separator;
		}

		ss << it->first << eq << it->second;
		count ++;
	}
	return UString(ss.str());
}

void UStringMap::clear()
{
	m_pimpl->clear();
}
